package gfx;

import javax.microedition.khronos.opengles.GL10;

import util.GameVars;
import util.VertexBuffer;

public class Firework {
	private Particle[] particleArray;
	static float[] particleSquare = new float[12];
	private boolean fireQueued;
	private boolean fired;
	
	private boolean nullTest;
	
	private short lane;

	private short creationIterator;
	private short updateIterator;
	private short drawIterator;
	
	private short resetIterator;
	
	public Firework(){
		nullTest = true;
		fired = false;
		particleArray = new Particle[GameVars.FIREWORK_PARTICLE_COUNT];
		
		particleSquare[0] = -GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[1] = -GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[2] = 0;
		particleSquare[3] = -GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[4] = GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[5] = 0;
		particleSquare[6] = GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[7] = -GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[8] = 0;
		particleSquare[9] = GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[10] = GameVars.PARTICLE_SQUARE_SIZE;
		particleSquare[11] = 0;
		
		for(creationIterator = 0; creationIterator < particleArray.length; ++creationIterator){
			particleArray[creationIterator] = new Particle((short) (creationIterator % GameVars.PARTICLE_COLOR_COUNT));
		}
	}
	
	public void update(long time){
		if(fireQueued)
			fired = true;

		if(!fired)
			return;

		if(nullTest){
			nullTest = false;
	
			for(updateIterator = 0; updateIterator < particleArray.length; ++updateIterator){
				if(particleArray[updateIterator].isDead())
					continue;
				
				nullTest = true;
				
				particleArray[updateIterator].update(time);
	
				if(particleArray[updateIterator].getX() < -Camera.GL_WIDTH || particleArray[updateIterator].getX() > Camera.GL_WIDTH){
					particleArray[updateIterator].kill();
					continue;
				}
				if(particleArray[updateIterator].getY() < -1)
					particleArray[updateIterator].kill();
			}
		}
	}
	
	public void draw(GL10 gl){
		if(!fired || !nullTest)
			return;
		
		gl.glPushMatrix();
		gl.glTranslatef(lane, 0, 0);
		
		for(drawIterator = 0; drawIterator < particleArray.length; ++drawIterator)
			if(particleArray[drawIterator] != null)
				particleArray[drawIterator].draw(gl);
		
		gl.glPopMatrix();
	}
	
	public void reset(){
		for(resetIterator = 0; resetIterator < particleArray.length; ++resetIterator)
			if(particleArray[resetIterator] != null)
				particleArray[resetIterator].reset();
		fireQueued = false;
		fired = false;
		nullTest = true;
	}
	
	public void fire(short lane){ fireQueued = true; this.lane = lane; }
	
	public boolean hasFired(){ return fired; }
	
	private class Particle{
		float x;
		float y;
		float yVelocity;
		float xVelocity;
		
		short color;
		
		boolean dead;
		
		public Particle(short color){
			x = 0;
			y = 0;
			this.color = color;
			
			dead = false;
			
			xVelocity = (float) (Math.random() * GameVars.PARTICLE_X_VELOCITY_MAX - GameVars.PARTICLE_X_VELOCITY_MAX * .5f);
			yVelocity = (float) (Math.random() * GameVars.PARTICLE_Y_VELOCITY_MAX);
		}
		
		public void update(long time){			
			x += xVelocity * time;
			y += yVelocity * time;
			
			yVelocity -= GameVars.PARTICLE_Y_VELOCITY_MOD * time;
		}
		
		public void draw(GL10 gl){
			gl.glPushMatrix();
			gl.glTranslatef(x, y, 0);
			switch(color){
			case GameVars.PARTICLE_COLOR_INDEX_RED:
				gl.glColor4f(1, 0, 0, 1);
				break;
			case GameVars.PARTICLE_COLOR_INDEX_BLUE:
				gl.glColor4f(0, 0, 1, 1);
				break;
			case GameVars.PARTICLE_COLOR_INDEX_GREEN:
				gl.glColor4f(0, 1, 0, 1);
				break;
			case GameVars.PARTICLE_COLOR_INDEX_YELLOW:
				gl.glColor4f(1, 1, 0, 1);
				break;
			case GameVars.PARTICLE_COLOR_INDEX_PURPLE:
				gl.glColor4f(1, 0, 1, 1);
				break;
			}
			
			gl.glDisable(GL10.GL_TEXTURE_2D);
			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glFrontFace(GL10.GL_CW);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VertexBuffer.getVertexBuffer(particleSquare));

			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, particleSquare.length / 3);
			
			gl.glColor4f(1, 1, 1, 1);
			gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glEnable(GL10.GL_TEXTURE_2D);
			
			gl.glPopMatrix();
		}
		
		public void reset(){
			x = 0;
			y = 0;
			
			xVelocity = (float) (Math.random() * GameVars.PARTICLE_X_VELOCITY_MAX - GameVars.PARTICLE_X_VELOCITY_MAX * .5f);
			yVelocity = (float) (Math.random() * GameVars.PARTICLE_Y_VELOCITY_MAX);
			
			dead = false;
		}
		
		public float getX(){ return x; }
		public float getY(){ return y; }
		public void kill(){ dead = true; }
		public boolean isDead(){ return dead; }
	}
}
